TOOL_CHAIN_PATH ?= /opt/gcc-riscv/riscv-wch-embedded-gcc-v1.70/bin
OPENOCD_PATH    ?= /opt/openocd/wch-openocd-v1.70/bin
PROJECT_NAME    = ch32v208wbu6_app

TOP_DIR     := .
OUTPUT_DIR  := $(TOP_DIR)/Build
STARTUP_DIR := $(TOP_DIR)/Startup
RISC_S_DIR := $(TOP_DIR)/FreeRTOS/portable/GCC/RISC-V


CORE_DIR    := $(TOP_DIR)/Core
DEBUG_DIR   := $(TOP_DIR)/Debug
SPL_DIR     := $(TOP_DIR)/Peripheral
USER_DIR    := $(TOP_DIR)/User
RTOS_DIR    :=  $(TOP_DIR)/FreeRTOS
RTOS_PORT_DIR    :=  $(TOP_DIR)/FreeRTOS/portable/GCC/RISC-V
RTOS_MM_DIR    :=  $(TOP_DIR)/FreeRTOS/portable/MemMang
#RTOS_CM_DIR    :=  $(TOP_DIR)/FreeRTOS/portable/Common

LD_FILE     := $(TOP_DIR)/Ld/Link.ld
OPENOCD_FILE := $(OPENOCD_PATH)/wch-riscv.cfg
MAP_FILE    := $(OUTPUT_DIR)/$(PROJECT_NAME).map
ELF_FILE    := $(OUTPUT_DIR)/$(PROJECT_NAME).elf
HEX_FILE    := $(OUTPUT_DIR)/$(PROJECT_NAME).hex
LST_FILE    := $(OUTPUT_DIR)/$(PROJECT_NAME).lst
SIZ_FILE    := $(OUTPUT_DIR)/$(PROJECT_NAME).siz

INCLUDES := $(INCLUDES)
INCLUDES += -IUser
INCLUDES += -ICore
INCLUDES += -IDebug
INCLUDES += -IPeripheral/inc
INCLUDES += -IFreeRTOS/include
INCLUDES += -IFreeRTOS/portable/GCC/RISC-V
INCLUDES += -IFreeRTOS/portable/GCC/RISC-V/chip_specific_extensions/RV32I_PFIC_no_extensions

CCFLAGS := \
-march=rv32imac -mabi=ilp32 -msmall-data-limit=8 -msave-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common -Wunused  -g 
all: $(HEX_FILE) $(LST_FILE) $(SIZ_FILE)

STARTUP_SRCS := $(wildcard $(STARTUP_DIR)/*.S)
STARTUP_OBJS := $(patsubst $(STARTUP_DIR)/%.S, $(OUTPUT_DIR)/startup/%.o, $(STARTUP_SRCS)) # patsubst: in #3 replace #1 to #2

RISC_S_SRCS := $(wildcard $(RISC_S_DIR)/*.S)
RISC_S_OBJS := $(patsubst $(RISC_S_DIR)/%.S, $(OUTPUT_DIR)/risc_s/%.o, $(RISC_S_SRCS)) # patsubst: in #3 replace #1 to #2


CORE_SRCS := $(wildcard $(CORE_DIR)/*.c)
CORE_OBJS := $(patsubst $(CORE_DIR)/%.c, $(OUTPUT_DIR)/core/%.o, $(CORE_SRCS))

DEBUG_SRCS := $(wildcard $(DEBUG_DIR)/*.c)
DEBUG_OBJS := $(patsubst $(DEBUG_DIR)/%.c, $(OUTPUT_DIR)/debug/%.o, $(DEBUG_SRCS))

SPL_SRCS := $(wildcard $(SPL_DIR)/src/*.c)
SPL_OBJS := $(patsubst $(SPL_DIR)/src/%.c, $(OUTPUT_DIR)/spl/%.o, $(SPL_SRCS))

USER_SRCS := $(wildcard $(USER_DIR)/*.c)
USER_OBJS := $(patsubst $(USER_DIR)/%.c, $(OUTPUT_DIR)/user/%.o, $(USER_SRCS))

RTOS_SRCS := $(wildcard $(RTOS_DIR)/*.c)
RTOS_OBJS := $(patsubst $(RTOS_DIR)/%.c, $(OUTPUT_DIR)/rtos/%.o, $(RTOS_SRCS))

RTOS_PORT_SRCS := $(wildcard $(RTOS_PORT_DIR)/*.c)
RTOS_PORT_OBJS := $(patsubst $(RTOS_PORT_DIR)/%.c, $(OUTPUT_DIR)/rtos_port/%.o, $(RTOS_PORT_SRCS))

RTOS_MM_SRCS := $(wildcard $(RTOS_MM_DIR)/*.c)
RTOS_MM_OBJS := $(patsubst $(RTOS_MM_DIR)/%.c, $(OUTPUT_DIR)/rtos_mm/%.o, $(RTOS_MM_SRCS))

#RTOS_CM_SRCS := $(wildcard $(RTOS_CM_DIR)/*.c)
#RTOS_CM_OBJS := $(patsubst $(RTOS_CM_DIR)/%.c, $(OUTPUT_DIR)/rtos_cm/%.o, $(RTOS_CM_SRCS))


$(OUTPUT_DIR)/startup/%.o: $(STARTUP_DIR)/%.S
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) -x assembler -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/risc_s/%.o: $(RISC_S_DIR)/%.S 
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -x assembler-with-cpp -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/core/%.o: $(CORE_DIR)/%.c
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/debug/%.o: $(DEBUG_DIR)/%.c
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/spl/%.o: $(SPL_DIR)/src/%.c
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/user/%.o: $(USER_DIR)/%.c
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/rtos/%.o: $(RTOS_DIR)/%.c
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/rtos_port/%.o: $(RTOS_PORT_DIR)/%.c
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

$(OUTPUT_DIR)/rtos_mm/%.o: $(RTOS_MM_DIR)/%.c
	@mkdir -p $(@D)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"

#$(OUTPUT_DIR)/rtos_cm/%.o: $(RTOS_CM_DIR)/%.c
#	@mkdir -p $(@D)
#	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) $(INCLUDES) -std=gnu99 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -c -o "$@" "$<"


$(ELF_FILE): $(STARTUP_OBJS) $(RISC_S_OBJS) $(CORE_OBJS) $(DEBUG_OBJS) $(SPL_OBJS)$(USER_OBJS) $(RTOS_OBJS) $(RTOS_PORT_OBJS) $(RTOS_MM_OBJS) 
	$(TOOL_CHAIN_PATH)/riscv-none-embed-gcc $(CCFLAGS) -T $(LD_FILE) -nostartfiles -Xlinker --gc-sections -Wl,-Map,$(MAP_FILE) --specs=nano.specs --specs=nosys.specs -o $(ELF_FILE) $(USER_OBJS) $(STARTUP_OBJS)$(DEBUG_OBJS)$(CORE_OBJS)$(SPL_OBJS)$(RTOS_OBJS) $(RTOS_PORT_OBJS)\
	$(RTOS_MM_OBJS)$(RISC_S_OBJS)

$(HEX_FILE): $(ELF_FILE)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-objcopy -O ihex $(ELF_FILE) $(HEX_FILE)

$(LST_FILE): $(ELF_FILE)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-objdump --all-headers --demangle --disassemble $(ELF_FILE) > $(LST_FILE)

$(SIZ_FILE): $(ELF_FILE)
	$(TOOL_CHAIN_PATH)/riscv-none-embed-size --format=berkeley $(ELF_FILE)


.PHONY: clean
clean:
	rm -f $(OUTPUT_DIR)/startup/*
	rm -f $(OUTPUT_DIR)/risc_s/*
	rm -f $(OUTPUT_DIR)/core/*
	rm -f $(OUTPUT_DIR)/debug/*
	rm -f $(OUTPUT_DIR)/spl/*
	rm -f $(OUTPUT_DIR)/user/*
	rm -f $(OUTPUT_DIR)/rtos/*
	rm -f $(OUTPUT_DIR)/rtos_port/*
	rm -f $(OUTPUT_DIR)/rtos_mm/*
	rm -f $(OUTPUT_DIR)/*.*

flash:
	$(OPENOCD_PATH)/openocd -f $(OPENOCD_FILE) -c init -c halt -c "flash erase_sector wch_riscv 0 last " -c "program $(ELF_FILE)" -c "verify_image $(ELF_FILE)" -c wlink_reset_resume -c exit

reset:
	$(OPENOCD_PATH)/openocd -f $(OPENOCD_FILE) -c init -c halt -c wlink_reset_resume -c exit

